﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using AllInOnePluginBL.Helpers;
using NLog;
using PluginDB;

namespace AllInOnePluginBL.SiteScrappers
{
    /// <summary>
    /// Summary description for SdarotOrgParserJob
    /// </summary>
    public class SdarotOrgParserJob : ISiteScapper
    {
        #region Private Members
        private const string CATEGORIES_URL = "http://www.sdarot.org/categories";
        private const string BASE_URL = "http://www.sdarot.org";
        protected const string SEARCH_URL = "http://www.sdarot.org/search?search_query={0}&search_type=videos";
        private const string NAME = "Sdarot.org";

        private readonly Logger _log = LogManager.GetLogger("SdarotOrgParserJob");
        private readonly PluginDBHandler _pluginDBHandler = PluginDBHandler.Instance;

        private class SeriesItem
        {
            public string Name { get; set; }
            public string ImageUrl { get; set; }
            public string PageUrl { get; set; }
            public string CookieString { get; set; }
        }
        #endregion

        public string Name { get; private set; }

        public JobType JobType { get; set; }

        public long JobID { get; set; }

        public SdarotOrgParserJob()
        {
            this.Name = NAME;
        }

        #region Implementation of IJob
        public void Execute(int pagesToRun)
        {
            _log.Debug("Start Executing SdarotOrgParserJob");

            var categories = this.LoadCategories();
            foreach (var category in categories)
            {
                this.LoadMovies(category);
            }

            _log.Debug("End Executing SdarotOrgParserJob");
        }
        #endregion

        #region Private Methods
        private IEnumerable<SeriesItem> LoadCategories()
        {
            var cookieString = Utils.GetCookieString(BASE_URL);
            var page = Utils.GetPageWithCookieHeader(CATEGORIES_URL, Encoding.UTF8, cookieString);

            const string categoriesLinkRegEx = "<div class=\"category_box\">.*?<a href=\"(.*?)\"><img src=\"(.*?)\".*?<div class=\"category_info\">(.*?)<";
            var matches = Regex.Matches(page, categoriesLinkRegEx, RegexOptions.Singleline);

            return (from Match match in matches
                    select new SeriesItem
                    {
                        Name = this.CleanString(match.Groups[3].Value),
                        ImageUrl = BASE_URL + match.Groups[2].Value,
                        PageUrl = (BASE_URL + match.Groups[1].Value).Replace("&amp;", "&"),
                        CookieString = cookieString
                    }).ToList();
        }

        private string CleanString(string str)
        {
            str = str.Replace("\r", string.Empty);
            str = str.Replace("\n", string.Empty);
            str = str.Replace("\t", string.Empty);
            return str;
        }

        private void LoadMovies(SeriesItem seriesItem)
        {
            try
            {
                var page = Utils.GetPageWithCookieHeader(seriesItem.PageUrl, Encoding.UTF8, seriesItem.CookieString);

                const string movieSectionRegEx = "<div class=\"video_box\">.*?<a href=\"(.*?)\"><img src=\"(.*?)\" title=\"(.*?)\"";
                var matches = Regex.Matches(page, movieSectionRegEx, RegexOptions.Singleline);

                foreach (Match match in matches)
                {
                    var moviePageLink = BASE_URL + match.Groups[1].Value;
                    var movieTitle = match.Groups[3].Value;
                    var imageLink = BASE_URL + match.Groups[2].Value;

                    if (_pluginDBHandler.IsVideoExists(moviePageLink))
                        continue;

                    var video = new PluginVideoInfo
                    {
                        VideoName = movieTitle,
                        PluginUrl = moviePageLink,
                        SiteName = NAME,
                        ImageUrl = imageLink,
                        IsHebSub = true
                    };

                    video.Categories.Add(seriesItem.Name);

                    video.Links.Add(new PluginVideoInfo.Link
                    {
                        LinkURL = moviePageLink,
                        SourceName = NAME
                    });

                    _pluginDBHandler.AddNewVideo(video);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        #endregion

    }
}